package com.huawei.esdk.uc.sametime.uccallbackimpl;

import java.util.Vector;

import org.apache.log4j.Logger;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;

import com.huawei.esdk.uc.jna.Constants;
import com.huawei.esdk.uc.jna.UCService;
import com.huawei.esdk.uc.jna.Constants.ContactAvailability;
import com.huawei.esdk.uc.jna.Constants.ReasonCode;
import com.huawei.esdk.uc.jna.Constants.SignInState;
import com.huawei.esdk.uc.jna.callback.ClientSignInNotifyCB;
import com.huawei.esdk.uc.sametime.EsdkPluginActivator;
import com.huawei.esdk.uc.sametime.history.ui.EsdkUCHistoryView;
import com.huawei.esdk.uc.sametime.international.Messages;
import com.huawei.esdk.uc.sametime.services.UCCallService;
import com.huawei.esdk.uc.sametime.services.UCLoginService;
import com.huawei.esdk.uc.sametime.services.UCSettingsService;
import com.huawei.esdk.uc.sametime.util.GlobalConfiguration;
import com.huawei.esdk.uc.sametime.util.PluginUtil;
import com.huawei.esdk.uc.sametime.widgets.CallComeInPopup;
import com.huawei.esdk.uc.sametime.widgets.EsdkUCConvWindow;
import com.ibm.collaboration.realtime.people.PeopleUtil;
import com.ibm.collaboration.realtime.people.Person;

/**
 * 登录回调对应的响应类
 * @author l00206777
 * 
 */
public class UCLoginCallBackImpl implements ClientSignInNotifyCB
{

    private Logger logger = Logger.getLogger(UCLoginCallBackImpl.class);

    private static UCLoginCallBackImpl instance = new UCLoginCallBackImpl();

    private Vector<UCLoginCallBackInterface> loginNotifyQueue;

    public synchronized static UCLoginCallBackImpl getInstance()
    {
        return instance;
    }

    private UCLoginCallBackImpl()
    {
        loginNotifyQueue = new Vector<UCLoginCallBackInterface>();
    }

    public void addObserver(UCLoginCallBackInterface observer)
    {
        loginNotifyQueue.add(observer);
    }

    public boolean removeObserver(UCLoginCallBackInterface observer)
    {
        return loginNotifyQueue.remove(observer);
    }

    @Override
    public void callBack(int state, String reason)
    {
        logger.debug("state is :" + state + " ,and reason is :" + reason);
        // 登录成功时候就开始设置一堆回调,登出时候或者登录失败则进行提示
        if (SignInState.Client_SignedIn == state)
        {
            // 如果登录成功,则将全局配置中的uc登录状态设置为已登录,并设置回调
            logger.debug("login successed");
            GlobalConfiguration.getInstance().setUCLogin(true);

            // 发布自己的状态
            UCService.getInstance().UC_SDK_PubSelfStatus(
                    ContactAvailability.Online, "");
            PeopleUtil.getLocalPerson().refreshStatus();

            Person[] persons = PeopleUtil.getPersons();
            if (null != persons)
            {
                String ucAccount;
                for (Person person : persons)
                {
                    ucAccount = PluginUtil.getUCAccountFromContactID(person
                            .getContactId());
                    // 订阅sametime联系人UC状态的改变通知
                    UCService.getInstance().UC_SDK_SubscribeStatus(ucAccount);

                    person.refreshStatus(); // 登录成功后刷新联系人信息
                }
            }

            // 设置呼叫事件回调
            UCService.getInstance().UC_SDK_SetCallEventCallBack(
                    UCVoiceCallBackImpl.getInstance().getClosedCB(),
                    UCVoiceCallBackImpl.getInstance().getConnectedCB(),
                    UCVoiceCallBackImpl.getInstance().getAddedCB());

            // 设置视频呼叫事件回调
            UCService.getInstance().UC_SDK_SetVideoCallEventCallBack(
                    UCVideoCallBackImpl.getInstance());

            // 设置会议成员变化事件回调
            UCService.getInstance().UC_SDK_SetConfMemEventCallBack(
                    UCConfMemEventCallBackImpl.getInstance());

            // 设置话机联动事件回调
            UCService.getInstance().UC_SDK_SetPhoneJointEventCallBack(
                    PhoneJointEventCBImpl.getInstance());

            // 设置视频设备、麦克风设备、扬声器设备
            UCSettingsService.setDevices();

            UpdateHistoryJob updateJob = new UpdateHistoryJob();
            Display.getDefault().syncExec(updateJob);
        }
        else
        {
            if (ReasonCode.ACC_KICKED.equals(reason))
            {
                UCLoginService.startLogoutUC();
            }

            logger.error("login failed with state: " + state + ", and reason: "
                    + reason);

            logger.debug("---------------------->set ucLogin false start");
            GlobalConfiguration.getInstance().setUCLogin(false);
            logger.debug("---------------------->set ucLogin false end");

            Display defaultDisPlay = Display.getDefault();

            if (null != EsdkPluginActivator.getDefault())
            {

                if (null != defaultDisPlay)
                {
                    CloseCallJob closeCallJob = new CloseCallJob();
                    defaultDisPlay.syncExec(closeCallJob);
                }

                Person[] persons = PeopleUtil.getPersons();
                if (null != persons)
                {
                    for (Person person : persons)
                    {
                        person.refreshStatus(); // 刷新联系人信息
                    }
                }
            }
            /*
             * 针对登录失败,还要再具体分析原因的,目前是先把出错原因打印出来
             */
            showLogoutErrorInfo(reason);

            UCCallService.clear();
            GlobalConfiguration.getInstance().resetUCConfig();
        }

        for (UCLoginCallBackInterface observer : loginNotifyQueue)
        {
            observer.handleLogin(state, reason);
        }
    }

    /**
     * 根据登出失败的原因字符串给出不同的提示信息框
     * @param reason 登录失败的原因字符串
     */
    private void showLogoutErrorInfo(String reason)
    {
        // 正常的uc登出不需要做提示
        if (reason.equals(Constants.ReasonCode.LOGOUT_OK))
        {
            logger.info(Constants.ReasonCode.LOGOUT_OK);
            return;
        }

        String tipsMsg = reason;
        if (reason.equals(Constants.ReasonCode.NOIP))
        {
            tipsMsg = Messages.UCLoginCallBackImpl_UC_DISCONNECT;
        }
        else if (reason.equals(Constants.ReasonCode.ACC_KICKED))
        {
            tipsMsg = Messages.UCLoginCallBackImpl_UC_KICKOFF;
        }
        else
        {
            tipsMsg = Messages.UCLoginCallBackImpl_UC_OTHER_ERROR;
        }
        final String msgToShow = tipsMsg;
        final String titleToShow = Messages.TIPS;
        ShowWarningJob warnJob = new ShowWarningJob(titleToShow, msgToShow);
        Display.getDefault().syncExec(warnJob);
    }

    private static class UpdateHistoryJob implements Runnable
    {
        @Override
        public void run()
        {
            if (null != EsdkUCHistoryView.getInstance())
            {
                // 呼叫及会议历史记录刷新
                EsdkUCHistoryView.getInstance().freshCallHistory();
                EsdkUCHistoryView.getInstance().freshConvHistory();
            }
        }
    }

    private static class ShowWarningJob implements Runnable
    {
        private String title;

        private String msg;

        public ShowWarningJob(String title, String msg)
        {
            this.title = title;
            this.msg = msg;
        }

        @Override
        public void run()
        {
            MessageDialog.openWarning(Display.getDefault().getActiveShell(),
                    this.title, this.msg);
        }
    }

    private static class CloseCallJob implements Runnable
    {
        @Override
        public void run()
        {
            // 掉线或登出时关闭来电和呼叫弹窗
            EsdkUCConvWindow.getInstance().closeContents();
            CallComeInPopup.getInstance().closeComeInPopup();
        }
    }
}
